#pragma once
#include <iostream>
#include <string>
#include <functional>
#include <sys/types.h>
#include <unistd.h>
#include <pthread.h>

namespace MyThread
{
    // 线程的状态
    enum class TDSTATUS
    {
        NEW,
        RUNNING,
        STOP
    };
    using func_t = std::function<void(std::string)>;
    static int threadnum = 1;

    class thread
    {
    private:
        // 因为在类中定义的接口都存在 this 指针 因此需要用 static 修饰类中函数
        static void* func(void* args)
        {
            thread* t = static_cast<thread*>(args);
            t->_func(t->getname());
            return nullptr;
        }
    
    public:
        thread(func_t f)
            :_func(f)
            ,_status(TDSTATUS::NEW)
            ,_joinable(true)
        {
            _name = "thread-" + std::to_string(threadnum++);
            _pid = getpid();
        }

        bool start()
        {
            if(_status == TDSTATUS::NEW)
            {
                _status = TDSTATUS::RUNNING;
                int ret = pthread_create(&_tid, nullptr, func, this);
                if(ret != 0) return false;

                return true;
            }
            return false;
        }

        bool join()
        {
            if(_status == TDSTATUS::RUNNING && _joinable)
            {
                int ret = pthread_join(_tid, nullptr);
                if(ret != 0) return false;

                return true;
            }
            return false;
        }

        bool joinable() { return _joinable; }
        
        bool stop()
        {
            int ret = pthread_cancel(_tid);
            if(ret != 0) return false;

            _status = TDSTATUS::STOP;
            return true;
        }

        bool detach()
        {
            _joinable = false;
            int ret = pthread_detach(_tid);
            if(ret != 0) return false;

            return true;
        }

        std::string getname()
        {
            return _name;
        }

        ~thread()
        {
            // do nothing
        }
    private:
        std::string _name;
        pthread_t _tid;
        pid_t _pid;
        func_t _func;
        TDSTATUS _status;
        bool _joinable;
    };
}